package com.magenta.maxoptra.gis;

import com.magenta.maxoptra.gis.util.Apis;

import javax.persistence.Column;
import java.io.Serializable;

import static com.magenta.maxoptra.gis.GisConstants.MAX_LATITUDE_ACCURACY;
import static com.magenta.maxoptra.gis.GisConstants.MAX_LONGITUDE_ACCURACY;

/*
* Project: MaxOptRA v1.1
* User: Ivan Usalko
* Date: 10.04.2009 22:12:15
*
* Copyright (c) 1999-2009 Magenta Corporation Ltd. All Rights Reserved.
* Magenta Technology proprietary and confidential.
* Use is subject to license terms.
*/
public class RouteRequestRecordPK implements Serializable {
    static final long serialVersionUID = 1952956454374980103L;

    //static final int MAX_LONGITUDE_ACCURACY = 6;
    //static final int MAX_LATITUDE_ACCURACY = 7;

    public Long cid;
    @Column
    public Integer lat1;
    @Column
    public Integer lon1;
    @Column
    public Integer lat2;
    @Column
    public Integer lon2;

    public RouteRequestRecordPK() { }

    public RouteRequestRecordPK(Long cid, Integer lat1, Integer lon1, Integer lat2, Integer lon2) {
    	this.cid = cid;
    	this.lat1 = lat1;
        this.lon1 = lon1;
        this.lat2 = lat2;
        this.lon2 = lon2;
    }

    public RouteRequestRecordPK(String providerName, String versionApi, String discriminator, Integer lat1, Integer lon1, Integer lat2, Integer lon2) {
    	this(Apis.cid(providerName, versionApi, discriminator), lat1, lon1, lat2, lon2);
    }

    private int hash(Object o) {
        return o != null ? o.hashCode() : 0;
    }

    @Override
    public int hashCode() {
        //return hash(cid) + hash(lat1) * 19 + hash(lon1) * 29 + hash(lat2) * 31 + hash(lon2) * 37;
        int result = (hash(cid) << 5 | hash(cid) >> 32 - 5);
        result ^= (hash(lat1) << 7 | hash(lat1) >> 32 - 7);
        result ^= (hash(lon1) << 11 | hash(lon1) >> 32 - 11);
        result ^= (hash(lat2) << 17 | hash(lat2) >> 32 - 17);
        result ^= (hash(lon1) << 19 | hash(lon2) >> 32 - 19);
        return result;
    }

    private boolean eq(Object obj1, Object obj2) {
        return obj1 == obj2 || (obj1 != null && obj1.equals(obj2));
    }

    private boolean vectorEq(RouteRequestRecordPK pk) {
        return eq(cid, pk.cid) && eq(lat1, pk.lat1) && eq(lon1, pk.lon1) && eq(lat2, pk.lat2) && eq(lon2, pk.lon2);
    }

    @Override
    public boolean equals(Object obj) {
        return obj instanceof RouteRequestRecordPK && vectorEq((RouteRequestRecordPK) obj);
    }

    public static void main(String[] args) {
    	String providerName = "anyone";
        String cid = "1L";
        int lat1 = 50000000;
        int lon1 = 0;
        int lat2 = 50000000;
        int lon2 = 0;
        RouteRequestRecordPK pk = new RouteRequestRecordPK(providerName, cid, "", lat1, lon1, lat2, lon2);
        int hash1 = pk.hashCode();
        System.out.println(String.format("HASH1 %d", hash1));
        cid = "826681511L";
        pk = new RouteRequestRecordPK(providerName, cid, "", lat1, lon1, lat2, lon2);
        int hash2 = pk.hashCode();
        System.out.println(String.format("HASH2 %d", hash2));
        System.out.println(String.format("HASH CODE DELTA: %d", hash1 - hash2));
        pk = new RouteRequestRecordPK(providerName, cid, "", lat1 + 100, lon1 - 100, lat2, lon2);
        int hash3 = pk.hashCode();
        System.out.println(String.format("HASH3 %d", hash3));
        System.out.println(String.format("HASH CODE DELTA: %d", hash2 - hash3));
        pk = new RouteRequestRecordPK(providerName, cid, "", lat1, lon1, lat2 + 100, lon2 - 100);
        int hash4 = pk.hashCode();
        System.out.println(String.format("HASH4 %d", hash4));
        System.out.println(String.format("HASH CODE DELTA: %d", hash3 - hash4));
        pk = new RouteRequestRecordPK(providerName, cid, "", lat1 + 100, lon1 + 100, lat2 + 100, lon2 + 100);
        int hash5 = pk.hashCode();
        System.out.println(String.format("HASH5 %d", hash5));
        System.out.println(String.format("HASH CODE DELTA: %d", hash4 - hash5));
        pk = new RouteRequestRecordPK(providerName, null, "", lat1 + 100, lon1 + 100, lat2 + 100, lon2 + 100);
        int hash6 = pk.hashCode();
        System.out.println(String.format("HASH6 %d", hash6));
        System.out.println(String.format("HASH CODE DELTA: %d", hash5 - hash6));
        pk = new RouteRequestRecordPK(providerName, null, "", lat1 - 100, lon1 - 100, lat2 - 100, lon2 - 100);
        int hash7 = pk.hashCode();
        System.out.println(String.format("HASH7 %d", hash7));
        System.out.println(String.format("HASH CODE DELTA: %d", hash6 - hash7));
    }

    public int getLongitudeAccuracy() {
        return MAX_LONGITUDE_ACCURACY;
    }

    public int getLatitudeAccuracy() {
        return MAX_LATITUDE_ACCURACY;
    }

	/**
	 * As array representation.
	 */
	public Object[] toArray() {
		return new Object[] {cid, lat1, lon1, lat2, lon2};
	}
}
